package com.yxinsur.imc.web.controller.business;

import java.util.ArrayList;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yxinsur.imc.business.domain.ImcOrderRisk;
import com.yxinsur.imc.business.enums.IsDeletedEnum;
import com.yxinsur.imc.business.enums.OrderStepEnum;
import com.yxinsur.imc.business.excel.OrderTemplate;
import com.yxinsur.imc.business.form.*;
import com.yxinsur.imc.business.service.IImcOrderRiskService;
import com.yxinsur.imc.business.service.IImcOrderService;
import com.yxinsur.imc.business.service.IImcRepoInsService;
import com.yxinsur.imc.business.vo.OrderDetailVo;
import com.yxinsur.imc.business.vo.OrderRiskVo;
import com.yxinsur.imc.business.vo.OrderVo;
import com.yxinsur.imc.business.vo.select.SelectIns;
import com.yxinsur.imc.common.exception.BusinessException;
import com.yxinsur.imc.common.utils.SecurityUtils;
import com.yxinsur.imc.common.utils.StringUtils;
import com.yxinsur.imc.system.service.ISysOrgService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.*;
import com.yxinsur.imc.common.annotation.Log;
import com.yxinsur.imc.common.core.controller.BaseController;
import com.yxinsur.imc.common.core.domain.AjaxResult;
import com.yxinsur.imc.common.enums.BusinessType;
import com.yxinsur.imc.common.utils.poi.ExcelUtil;
import com.yxinsur.imc.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;

/**
 * 保单Controller
 *
 * @author imc
 * @date 2021-03-18
 */
@Api(value="保单模块接口服务",tags={"2.1.保单模块接口服务"})
@RestController
@RequestMapping("/business/order")
public class ImcOrderController extends BaseController
{
    @Autowired
    private IImcOrderService imcOrderService;
    @Autowired
    private IImcOrderRiskService imcOrderRiskService;
    @Autowired
    private IImcRepoInsService imcRepoInsService;
    @Autowired
    private ISysOrgService sysOrgService;
    /**
     * 查询保单列表
     */
    @Log(title = "保单列表查询")
    @GetMapping("/list")
    @ApiOperation("保单列表查询")
    public TableDataInfo list(OrderSearchForm searchForm)
    {
        if(StringUtils.isNotBlank(searchForm.getInputOrgId())){
            searchForm.setInputOrgId(this.sysOrgService.selectChildOrgIds(Long.valueOf(searchForm.getInputOrgId())));
        }
        startPage();
        List<OrderVo> list = imcOrderService.selectQueryOrderList(searchForm);
        return getDataTable(list);
    }

    /**
     * 导出保单列表
     */
    @Log(title = "保单导出", businessType = BusinessType.EXPORT)
    @ApiOperation("保单列表导出")
    @GetMapping("/export")
    public AjaxResult export(OrderSearchForm searchForm)
    {
        if(StringUtils.isNotBlank(searchForm.getInputOrgId())){
            searchForm.setInputOrgId(this.sysOrgService.selectChildOrgIds(Long.valueOf(searchForm.getInputOrgId())));
        }
        List<OrderVo> list = imcOrderService.selectQueryOrderList(searchForm);
        ExcelUtil<OrderVo> util = new ExcelUtil<OrderVo>(OrderVo.class);
        return util.exportExcel(list, "保单查询列表数据");
    }

    @ApiOperation("保单导入模板下载")
    @GetMapping("/importTemplate")
    public AjaxResult importTemplate()
    {
        ExcelUtil<OrderTemplate> util = new ExcelUtil<OrderTemplate>(OrderTemplate.class);
        return util.importTemplateExcel("保单导入模板");
    }

    @ApiOperation("保单详情查询")
    @PostMapping("/get/{orderId}")
    public AjaxResult getDetail(@PathVariable("orderId") Long orderId) throws Exception
    {
        OrderDetailVo vo = this.imcOrderService.getByOrderId(orderId);
        return AjaxResult.success(vo);
    }

    @ApiOperation("保单导入（inputOrgId：机构ID,repoSupplierId:供应商ID）")
    @PostMapping("/importData/{inputOrgId}/{repoSupplierId}")
    public AjaxResult importData(MultipartFile file, @PathVariable("inputOrgId") Long inputOrgId, @PathVariable("repoSupplierId") Long repoSupplierId) throws Exception
    {
        ExcelUtil<OrderTemplate> util = new ExcelUtil<OrderTemplate>(OrderTemplate.class);
        List<OrderTemplate> orderList = util.importExcel(file.getInputStream());
        String message = this.imcOrderService.importOrder(inputOrgId,repoSupplierId,orderList,false);
        return AjaxResult.success(message);
    }

    @Log(title = "查询保单下险种下拉数据")
    @ApiOperation("查询保单下险种下拉数据")
    @PostMapping("/risks/{orderId}")
    public AjaxResult orderRisks(@PathVariable("orderId") Long orderId)
    {
        QueryWrapper<ImcOrderRisk> riskQueryWrapper = new QueryWrapper<>();
        riskQueryWrapper.eq("pay_num",1);//仅查询首期
        riskQueryWrapper.eq("order_id",orderId);
        riskQueryWrapper.eq("is_deleted", IsDeletedEnum.N.getCode());
        riskQueryWrapper.eq("tenant_id", SecurityUtils.getTenantId());
        List<ImcOrderRisk> risks = this.imcOrderRiskService.list(riskQueryWrapper);
        List<SelectIns> selectInsList = new ArrayList<>();
        for (ImcOrderRisk risk:risks) {
            SelectIns ins = new SelectIns();
            ins.setId(risk.getId());
            ins.setInsCode(risk.getInsCode());
            ins.setRiskName(risk.getRiskName());
            ins.setRiskShortName(risk.getRiskName());
            selectInsList.add(ins);
        }
        return AjaxResult.success(selectInsList);
    }
    /**
     * 投保录入
     */
    @ApiOperation("投保录入")
    @Log(title = "投保录入", businessType = BusinessType.INSERT)
    @PostMapping("/insure")
    public AjaxResult insureInput(@RequestBody OrderDataForm order)
    {
        imcOrderService.insureOrder(order);
        return AjaxResult.success();
    }
    @GetMapping("/input/list")
    @ApiOperation("保单录入列表查询")
    public TableDataInfo inputList(OrderSearchForm searchForm)
    {
        if(StringUtils.isNotBlank(searchForm.getInputOrgId())){
            searchForm.setInputOrgId(this.sysOrgService.selectChildOrgIds(Long.valueOf(searchForm.getInputOrgId())));
        }
        startPage();
        List<OrderVo> list = imcOrderService.selectInputOrderList(searchForm);
        return getDataTable(list);
    }
    /**
     * 承保录入
     */
    @ApiOperation("承保录入")
    @Log(title = "承保录入", businessType = BusinessType.INSERT)
    @PostMapping("/accept")
    public AjaxResult acceptInput(@RequestBody OrderDataForm order)
    {
        imcOrderService.updateImcOrder(order, OrderStepEnum.ACCEPT_INSURE);
        return AjaxResult.success();
    }

    /**
     * 保单删除
     */
    @ApiOperation("保单删除")
    @Log(title = "保单删除", businessType = BusinessType.DELETE)
    @DeleteMapping("/delete/{orderIds}")
    public AjaxResult delete(@PathVariable Long orderIds)
    {
        imcOrderService.deleteOrderCheck(orderIds);
        imcOrderService.deleteOrder(orderIds);
        return AjaxResult.success();
    }

    /**
     * 保单批改
     */
    @ApiOperation("保单批改")
    @Log(title = "保单批改", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody OrderDataForm order){
        imcOrderService.updateImcOrder(order,OrderStepEnum.ORDER_EDIT);
        return AjaxResult.success();
    }
    @GetMapping("/cancel/list")
    @ApiOperation("保单撤销列表查询")
    public TableDataInfo cancelList(OrderSearchForm searchForm)
    {
        if(StringUtils.isNotBlank(searchForm.getInputOrgId())){
            searchForm.setInputOrgId(this.sysOrgService.selectChildOrgIds(Long.valueOf(searchForm.getInputOrgId())));
        }
        startPage();
        List<OrderVo> list = imcOrderService.selectCancelOrderList(searchForm);
        return getDataTable(list);
    }

    /**
     * 导出保单列表
     */
    @ApiOperation("保单撤销列表导出")
    @GetMapping("/cancel/export")
    public AjaxResult cancelListExport(OrderSearchForm searchForm)
    {
        if(StringUtils.isNotBlank(searchForm.getInputOrgId())){
            searchForm.setInputOrgId(this.sysOrgService.selectChildOrgIds(Long.valueOf(searchForm.getInputOrgId())));
        }
        List<OrderVo> list = imcOrderService.selectCancelOrderList(searchForm);
        ExcelUtil<OrderVo> util = new ExcelUtil<OrderVo>(OrderVo.class);
        return util.exportExcel(list, "保单撤销列表数据");
    }

    /**
     * 保单撤销
     * @param order
     * @return
     */
    @Log(title = "保单撤销", businessType = BusinessType.UPDATE)
    @ApiOperation("保单撤销")
    @PutMapping("/cancel")
    public AjaxResult cancel(@RequestBody OrderCancelForm order){
        imcOrderService.cancelImcOrder(order);
        return AjaxResult.success();
    }

    /**
     * 险种豁免
     * @param order
     * @return
     */
    @Log(title = "险种豁免", businessType = BusinessType.UPDATE)
    @ApiOperation("险种豁免")
    @PutMapping("/waiver/risk")
    public AjaxResult waiverRisk(@RequestBody OrderRiskWaiverForm order){
        imcOrderService.waiverImcOrderRisk(order);
        return AjaxResult.success();
    }

    @GetMapping("/end/list")
    @ApiOperation("保单终止列表查询")
    public TableDataInfo endList(OrderSearchForm searchForm)
    {
        if(StringUtils.isNotBlank(searchForm.getInputOrgId())){
            searchForm.setInputOrgId(this.sysOrgService.selectChildOrgIds(Long.valueOf(searchForm.getInputOrgId())));
        }
        startPage();
        List<OrderVo> list = imcOrderService.selectEndOrderList(searchForm);
        return getDataTable(list);
    }
    /**
     * 导出保单列表
     */
    @ApiOperation("保单终止列表导出")
    @GetMapping("/end/export")
    public AjaxResult endListExport(OrderSearchForm searchForm)
    {
        if(StringUtils.isNotBlank(searchForm.getInputOrgId())){
            searchForm.setInputOrgId(this.sysOrgService.selectChildOrgIds(Long.valueOf(searchForm.getInputOrgId())));
        }
        List<OrderVo> list = imcOrderService.selectEndOrderList(searchForm);
        ExcelUtil<OrderVo> util = new ExcelUtil<OrderVo>(OrderVo.class);
        return util.exportExcel(list, "保单终止列表数据");
    }
    /**
     * 保单终止
     * @param order
     * @return
     */
    @Log(title = "保单终止", businessType = BusinessType.UPDATE)
    @ApiOperation("保单终止")
    @PutMapping("/end")
    public AjaxResult end(@RequestBody OrderEndForm order){
        imcOrderService.endImcOrder(order);
        return AjaxResult.success();
    }
    /**
     * 险种终止
     * @param order
     * @return
     */
    @Log(title = "险种终止", businessType = BusinessType.UPDATE)
    @ApiOperation("险种终止")
    @PutMapping("/end/risk")
    public AjaxResult endRisk(@RequestBody OrderRiskEndForm order){
        imcOrderService.endImcOrderRisk(order);
        return AjaxResult.success();
    }

    @GetMapping("/receipt/list")
    @ApiOperation("保单回执列表查询")
    public TableDataInfo receiptList(OrderSearchForm searchForm)
    {
        if(StringUtils.isNotBlank(searchForm.getInputOrgId())){
            searchForm.setInputOrgId(this.sysOrgService.selectChildOrgIds(Long.valueOf(searchForm.getInputOrgId())));
        }
        startPage();
        List<OrderVo> list = imcOrderService.selectReceiptOrderList(searchForm);
        return getDataTable(list);
    }
    /**
     * 导出保单列表
     */
    @ApiOperation("保单回执列表导出")
    @GetMapping("/receipt/export")
    public AjaxResult receiptListExport(OrderSearchForm searchForm)
    {
        if(StringUtils.isNotBlank(searchForm.getInputOrgId())){
            searchForm.setInputOrgId(this.sysOrgService.selectChildOrgIds(Long.valueOf(searchForm.getInputOrgId())));
        }
        List<OrderVo> list = imcOrderService.selectCancelOrderList(searchForm);
        ExcelUtil<OrderVo> util = new ExcelUtil<OrderVo>(OrderVo.class);
        return util.exportExcel(list, "保单回执列表数据");
    }

    /**
     * 保单回执
     * @param order
     * @return
     */
    @Log(title = "保单回执", businessType = BusinessType.UPDATE)
    @ApiOperation("保单回执")
    @PutMapping("/receipt")
    public AjaxResult receipt(@RequestBody OrderReceiptForm order){
        imcOrderService.receiptImcOrder(order);
        return AjaxResult.success();
    }


    @GetMapping("/non/annual/list")
    @ApiOperation("非年交保单分页列表查询")
    public TableDataInfo nonAnnualList(OrderSearchForm searchForm)
    {
        if(StringUtils.isNotBlank(searchForm.getInputOrgId())){
            searchForm.setInputOrgId(this.sysOrgService.selectChildOrgIds(Long.valueOf(searchForm.getInputOrgId())));
        }
        startPage();
        List<OrderVo> list = imcOrderService.selectNonAnnualOrderList(searchForm);
        return getDataTable(list);
    }

    @GetMapping("/{orderId}/payment/record/list")
    @ApiOperation("缴费记录分页列表查询")
    public TableDataInfo paymentRecordList(@PathVariable Long orderId)
    {
        startPage();
        List<OrderRiskVo> list = imcOrderService.selectOrderRiskList(orderId);
        return getDataTable(list);
    }

    /**
     * 新增缴费记录
     */
    @Log(title = "新增缴费记录", businessType = BusinessType.INSERT)
    @ApiOperation("新增缴费记录")
    @PostMapping("/{orderId}/payment/record")
    public AjaxResult addPaymentRecord(@RequestBody OrderRiskInputForm risk, @PathVariable Long orderId)
    {
        imcOrderService.addOrderRisk(orderId,risk);
        return AjaxResult.success();
    }

    @GetMapping("/renewal/list")
    @ApiOperation("续期查询分页列表查询")
    public TableDataInfo renewalList(RenewalOrderSearchForm searchForm)
    {
        startPage();
        List<OrderRiskVo> list = imcOrderService.selectRenewalRiskList(searchForm);
        return getDataTable(list);
    }

    @Log(title = "续期险种信息修改", businessType = BusinessType.UPDATE)
    @GetMapping("/renewal/edit")
    @ApiOperation("续期险种信息修改")
    public AjaxResult renewaledit(OrderRiskInputForm risk)
    {
        this.imcOrderRiskService.renewalRiskEdit(risk);
        return AjaxResult.success();
    }


    @Log(title = "续期险种信息追加", businessType = BusinessType.INSERT)
    @PostMapping("/renewal/add")
    @ApiOperation("续期险种信息追加")
    public AjaxResult renewalAdd(@RequestBody OrderRiskInputForm risk)
    {
        try {
            this.imcOrderRiskService.renewalAdd(risk);
        } catch (Exception e) {
            if(e instanceof DuplicateKeyException){
                logger.error("错误异常信息："+e.getMessage());
                throw new BusinessException("追加险种的保单年度，缴费期数已存在，请检查");
                // "该接口数据主键冲突"+e.getMessage()
            }else {
                throw new BusinessException("追加险种异常："+e.getMessage());
                //"未知异常："+e.getMessage()
            }

        }
        return AjaxResult.success();
    }

    @Log(title = "续期险种信息删除", businessType = BusinessType.DELETE)
    @PostMapping("/renewal/delete/{orderRiskId}")
    @ApiOperation("续期险种信息删除")
    public AjaxResult renewalDelete(@PathVariable Long orderRiskId)
    {
        this.imcOrderRiskService.renewalDelete(orderRiskId);
        return AjaxResult.success();
    }

    /**
     * 保单转移
     */
    @Log(title = "保单转移", businessType = BusinessType.UPDATE)
    @ApiOperation("保单转移")
    @PostMapping("/transfer/to/{brokerId}/")
    public AjaxResult transfer(@RequestBody List<Long> orderIds, @PathVariable Long brokerId)
    {
        int count = imcOrderService.transferOrder(brokerId,orderIds);
        return AjaxResult.success("保单转移完毕，影响保单数:"+count+"个");
    }
}
